package com.stox.ui.javafx.core.widget;

import java.util.Locale;

import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Button;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;

import org.controlsfx.control.textfield.CustomTextField;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import com.stox.design.Callback;
import com.stox.dto.AbstractModel;
import com.stox.dto.intf.AbstractModelSearchable;
import com.stox.event.AbstractModelSelectionEvent;

@Component("searchPanel")
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class AbstractModelSearchPanel extends HBox implements EventHandler<KeyEvent>, InitializingBean {
	
	@Autowired
	private ApplicationContext applicationContext;
	
	private AbstractModelSearchable abstractModelSearchable;
	
	private final Button previousButton = new Button();
	
	private final Button nextButton = new Button();
	
	private final CustomTextField textField  = new CustomTextField();
	
	public AbstractModelSearchPanel() {
		textField.setRight(new HBox(nextButton, previousButton));
		previousButton.getStyleClass().add("up-arrow");
		nextButton.getStyleClass().add("down-arrow");
		previousButton.setOnAction(new EventHandler<ActionEvent>(){
			public void handle(ActionEvent event) {
				publicAbstractModelSelectionEvent(false);
				event.consume();
			};
		});
		
		nextButton.setOnAction(new EventHandler<ActionEvent>(){
			@Override
			public void handle(ActionEvent event) {
				publicAbstractModelSelectionEvent(true);
				event.consume();
			}
		});
		
		this.textField.setOnKeyPressed(this);
		HBox.setHgrow(textField, Priority.ALWAYS);
		this.getChildren().addAll(textField);
	}
	
	@Override
	public void afterPropertiesSet() throws Exception {
		textField.setPromptText(applicationContext.getMessage("Search", null, Locale.getDefault()));
	}
	
	public AbstractModelSearchable getabstractModelSearchable() {
		return abstractModelSearchable;
	}
	
	public void setabstractModelSearchable(
			AbstractModelSearchable abstractModelSearchable) {
		this.abstractModelSearchable = abstractModelSearchable;
	}
	
	private void publicAbstractModelSelectionEvent(boolean forward){
		if(null == abstractModelSearchable) return;
		String text = textField.getText();
		if(null == text) text = "";
		text = text.trim().toUpperCase();
		doSearch(text,0, forward);
	}
	
	private void doSearch(final String text,int start,  boolean forward){
		abstractModelSearchable.search(new Callback<AbstractModel, Boolean>(){
			@Override
			public Boolean execute(AbstractModel abstractModel) {
				return null != abstractModel &&
						((null != abstractModel.getName() && abstractModel.getName().trim().toUpperCase().contains(text.trim().toUpperCase())) 
						|| (null != abstractModel.getId() && abstractModel.getId().toString().toUpperCase().contains(text.trim().toUpperCase())));
			}
		},start, forward);
	}
	
	@Override
	public void handle(KeyEvent event) {
		if(null == abstractModelSearchable) return;
		if(event.getCode() == KeyCode.ENTER ) {
			applicationContext.publishEvent(new AbstractModelSelectionEvent(abstractModelSearchable));
		}else if(event.getCode() == KeyCode.UP){
			previousButton.fire();
		}else if(event.getCode() == KeyCode.DOWN){
			nextButton.fire();
		}else{
			final String text = (textField.getText()+event.getText()).trim().toUpperCase();
			doSearch(text, -1, true);
		}
	}
	
}
